import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
import { produce } from "immer";
import { get, set, del } from "idb-keyval";
import { v4 as uuidv4 } from "uuid";

const storage = {
  getItem: async (name) => {
    return (await get(name)) || null;
  },
  setItem: async (name, value) => {
    await set(name, value);
  },
  removeItem: async (name) => {
    await del(name);
  },
};
const initId = uuidv4();
export const BOARD_VERSION = "1.3.0";

const useFileStore = create(
  persist(
    (set, get) => ({
      currentId: initId,
      files: [
        {
          id: initId,
          title: "own-file",
          boardVersion: BOARD_VERSION,
          boardData: {},
          zoom: 1,
          canvasWidth: 1,
          canvasHeight: 1,
        },
      ],
      updateCurrentFileId(id) {
        const currentId = get().currentId;
        if (currentId != id) {
          set({ currentId: id });
        }
      },
      updateTitle(newTitle, id) {
        const files = get().files;
        const updateIndex = files?.findIndex((file) => file.id === id);
        if (files?.[updateIndex]?.title !== newTitle) {
          set(
            produce((state) => {
              state.files[updateIndex].title = newTitle;
            })
          );
        }
      },
      updateBoardData(data) {
        const files = get().files;
        const updateIndex = files?.findIndex(
          (file) => file.id === get().currentId
        );
        set(
          produce((state) => {
            state.files[updateIndex].boardVersion = BOARD_VERSION;
            state.files[updateIndex].boardData = data;
          })
        );
      },
      updateZoom(newZoom) {
        const files = get().files;
        const updateIndex = files?.findIndex(
          (file) => file.id === get().currentId
        );
        if (updateIndex > -1) {
          set(
            produce((state) => {
              state.files[updateIndex].zoom = newZoom;
            })
          );
        }
      },
      updateTransform(newTransform) {
        const files = get().files;
        const updateIndex = files?.findIndex(
          (file) => file.id === get().currentId
        );
        if (updateIndex > -1) {
          set(
            produce((state) => {
              state.files[updateIndex].viewportTransform = newTransform;
            })
          );
        }
      },
      updateCanvasWidth(width) {
        const files = get().files;
        const updateIndex = files?.findIndex(
          (file) => file.id === get().currentId
        );
        if (updateIndex > -1) {
          set(
            produce((state) => {
              state.files[updateIndex].canvasWidth = width;
            })
          );
        }
      },
      updateCanvasHeight(height) {
        const files = get().files;
        const updateIndex = files?.findIndex(
          (file) => file.id === get().currentId
        );
        if (updateIndex > -1) {
          set(
            produce((state) => {
              state.files[updateIndex].canvasHeight = height;
            })
          );
        }
      },
      addFile() {
        const id = uuidv4();
        set(
          produce((state) => {
            state.files.unshift({
              id,
              title: "empty title",
              boardVersion: BOARD_VERSION,
              boardData: {},
              zoom: 1,
              canvasWidth: 1,
              canvasHeight: 1,
            });
          })
        );
      },
      deleteFile() {
        const files = get().files;
        if (files.length > 1) {
          const updateIndex = files?.findIndex(
            (file) => file.id === get().currentId
          );
          set(
            produce((state) => {
              state.files.splice(updateIndex, 1);
              state.currentId = state.files[0].id;
            })
          );
        }
      },
    }),
    {
      name: "file-storage",
      storage: createJSONStorage(() => storage),
    }
  )
);
export default useFileStore;
// createJSONStorage 允许你定义如何序列化（存储）和反序列化（恢复）状态，从而支持不同的存储机制。默认情况下，zustand 的 persist
// 中间件使用 localStorage 来存储状态，且使用 JSON 格式来序列化和反序列化状态数据。通过 createJSONStorage，你可以扩展或更改这些
// 行为以适应不同的需求，比如使用 IndexedDB、Cookies 或者其他 Web 存储解决方案。

// 1.IDB-Keyval 是一个使用 IndexedDB 实现的极其简单、基于 Promise 的键值存储库。以下是关于它的一些主要特点和功能介绍：
// 极简高效：该库设计精巧，非常高效，支持树摇（tree-shaking）。如果你只使用基础的 get 和 set 方法，库的大小约为 250 字节（使用 brotli 压缩）。如果使用所有方法，大小会增加到约 534 字节。
// 2.易于使用：IDB-Keyval 简化了 IndexedDB 的使用，提供了一个简单的 API 进行键值存储，比直接使用 IndexedDB 更容易操作。
// 3.基于 Promise：它通过 Promise 进行异步操作，符合现代 JavaScript 实践，包括 async/await。
// 主要功能：
// get(key): 通过键名检索值。
// set(key, value): 设置一个指定键名下的值。
// delete(key): 删除一个键及其关联的值。
// clear(): 清除存储中的所有条目。
// 适用场景：IDB-Keyval 非常适合需要在客户端简单高效地存储数据，而不需管理复杂数据库架构的应用程序。
// 对比：功能上与 localForage 相似，但在体积上要小得多，非常适合对项目大小有严格要求的场景。
